# 将田块作物转换成待遍历的堆积点
import numpy as np
import math
import matplotlib.pyplot as plt
import pandas as pd


class splitfield:
    def __init__(self, length_field, width_field, harvest_width):
        self.length_field = length_field
        self.width_field = width_field
        self.harvest_width = harvest_width

    def field_boundary(self):                                              # 生成田块边界点坐标
        boundary_field_xaxis = [0, self.length_field, self.length_field, 0, 0]
        boundary_field_yaxis = [0, 0, self.width_field, self.width_field, 0]
        return boundary_field_xaxis, boundary_field_yaxis

    def split_side(self):                                                  # 按边长生成分割点列表,对边上的点操作
        length_field_side_xaxis = []
        length_field_side_yaxis_down = [0]
        length_field_side_yaxis_up = [self.width_field]
        width_field_side_xaxis_down = [0]
        width_field_side_xaxis_up = [self.length_field]
        width_field_side_yaxis = []
        if self.length_field % self.harvest_width == 0:
            length_point_num = int((self.length_field / self.harvest_width) + 1)
            length_field_side_yaxis_down = length_field_side_yaxis_down * length_point_num  # 返回具有同样元素个数的长边纵坐标，‘0‘
            length_field_side_yaxis_up = length_field_side_yaxis_up * length_point_num      # 返回具有同样元素个数的长边纵坐标，‘宽‘
            for i in range(0, length_point_num):
                length_xaxis = i * self.harvest_width
                length_field_side_xaxis.append(length_xaxis)
            if self.width_field % self.harvest_width == 0:
                width_point_num = int((self.width_field / self.harvest_width) + 1)
                width_field_side_xaxis_down = width_field_side_xaxis_down * width_point_num
                width_field_side_xaxis_up = width_field_side_xaxis_up * width_point_num
                for i in range(0, width_point_num):
                    width_yaxis = i * self.harvest_width
                    width_field_side_yaxis.append(width_yaxis)
            else:
                width_point_num = int(int(self.width_field / self.harvest_width) + 2)
                width_field_side_xaxis_down = width_field_side_xaxis_down * width_point_num
                width_field_side_xaxis_up = width_field_side_xaxis_up * width_point_num
                for i in range(0, width_point_num - 1):
                    width_yaxis = i * self.harvest_width
                    width_field_side_yaxis.append(width_yaxis)
                width_yaxis_last = self.width_field
                width_field_side_yaxis.append(width_yaxis_last)
        else:
            length_point_num = int((self.length_field / self.harvest_width) + 2)
            length_field_side_yaxis_down = length_field_side_yaxis_down * length_point_num
            length_field_side_yaxis_up = length_field_side_yaxis_up * length_point_num
            for i in range(0, length_point_num - 1):
                length_xaxis = i * self.harvest_width
                length_field_side_xaxis.append(length_xaxis)
            length_xaxis_last = self.length_field
            length_field_side_xaxis.append(length_xaxis_last)
            if self.width_field % self.harvest_width == 0:
                width_point_num = int((self.width_field / self.harvest_width) + 1)
                width_field_side_xaxis_down = width_field_side_xaxis_down * width_point_num
                width_field_side_xaxis_up = width_field_side_xaxis_up * width_point_num
                for i in range(0, width_point_num):
                    width_yaxis = i * self.harvest_width
                    width_field_side_yaxis.append(width_yaxis)
            else:
                width_point_num = int(int(self.width_field / self.harvest_width) + 2)
                width_field_side_xaxis_down = width_field_side_xaxis_down * width_point_num
                width_field_side_xaxis_up = width_field_side_xaxis_up * width_point_num
                for i in range(0, width_point_num - 1):
                    width_yaxis = i * self.harvest_width
                    width_field_side_yaxis.append(width_yaxis)
                width_yaxis_last = self.width_field
                width_field_side_yaxis.append(width_yaxis_last)
        return length_field_side_xaxis, length_field_side_yaxis_down, length_field_side_yaxis_up, width_field_side_yaxis, width_field_side_xaxis_down, width_field_side_xaxis_up

    def specificaxis(self):                                             # 对得到的点列表进行组合，确定线两端的端点坐标
        l_x, l_y_l, l_y_u, w_y, w_x_l, w_x_u = self.split_side()
        length_draw_line_xaxis = []
        length_draw_line_yaxis = []
        for i in range(0, len(l_x)):
            length_pointx = []
            length_pointy = []
            a = l_x[i]
            b = a
            length_pointx.append(a)
            length_pointx.append(b)
            length_point_down_y = l_y_l[i]
            length_point_up_y = l_y_u[i]
            length_pointy.append(length_point_down_y)
            length_pointy.append(length_point_up_y)
            length_draw_line_xaxis.append(length_pointx)
            length_draw_line_yaxis.append(length_pointy)
        width_draw_line_xaxis = []
        width_draw_line_yaxis = []
        for i in range(0, len(w_y)):
            width_pointx = []
            width_pointy = []
            a = w_y[i]
            b = a
            width_pointy.append(a)
            width_pointy.append(b)
            width_point_down_x = w_x_l[i]
            width_point_up_x = w_x_u[i]
            width_pointx.append(width_point_down_x)
            width_pointx.append(width_point_up_x)
            width_draw_line_xaxis.append(width_pointx)
            width_draw_line_yaxis.append(width_pointy)
        return length_draw_line_xaxis, length_draw_line_yaxis, width_draw_line_xaxis, width_draw_line_yaxis

    def accumulate_point_axis(self):                                         # 设分行相交点为堆积点
        point_x = []
        point_y = []
        accpoint_line_y = []
        l_x, l_y, w_x, w_y = self.specificaxis()
        for i in range(1, len(l_x)):
            accpoint_x = l_x[i][0]
            num_pointx = len(w_x) - 1
            for j in range(num_pointx):
                point_x.append(accpoint_x)
        for i in range(1, len(w_y)):
            accpoint_y = w_y[i][0]
            accpoint_line_y.append(accpoint_y)                               # 生成一列上点的纵坐标集合
        num_line_y = len(l_x) - 1
        for j in range(num_line_y):                                     # 根据列数合并纵坐标，形成一个大列表
            point_y.extend(accpoint_line_y)
        return point_x, point_y

    def draw_graphic(self):
        boundary_x, boundary_y = self.field_boundary()
        length_point_x, length_point_y, width_point_x, width_point_y = self.specificaxis()
        accmulate_point_x, accmulate_point_y = self.accumulate_point_axis()
        n = np.arange(len(accmulate_point_x))
        plt.plot(boundary_x, boundary_y, color='k', linestyle='-', linewidth=3)
        for i in range(1, len(length_point_x)-1):
            plt.plot(length_point_x[i], length_point_y[i], color='b', linestyle='-', linewidth=2)
        for i in range(1, len(width_point_x)-1):
            plt.plot(width_point_x[i], width_point_y[i], color='r', linestyle='-', linewidth=2)
        plt.rcParams['font.sans-serif'] = ['SimHei']
        # fig, ax = plt.subplots()
        plt.scatter(accmulate_point_x, accmulate_point_y, s=math.pi*(self.harvest_width ** 2), c='g', marker='o', label='粮食堆积点')
        for i, txt in enumerate(n):
            plt.annotate(txt, (accmulate_point_x[i], accmulate_point_y[i]))
        # box = ax.get_position()
        # ax.set_position([box.x0, box.y0, box.width, box.height * 0.8])
        # plt.legend(loc='upper right')
        plt.xticks([])
        plt.yticks([])
        plt.axis('off')
        plt.show()

    def accumulate_point(self):                                              # 输出堆积点编号及坐标
        accmulate_point_x, accmulate_point_y = self.accumulate_point_axis()
        number_point = []
        for i in range(len(accmulate_point_x)):
            number_point.append(i)
        # n = np.arange(len(accmulate_point_x))
        output_axis = {'pointnum': number_point, 'xpoint': accmulate_point_x, 'ypoint': accmulate_point_y}
        # output_axis['pointnum'] = number_point
        # output_axis['xpoint'] = accmulate_point_x
        # output_axis['ypoint'] = accmulate_point_y
        output = pd.DataFrame(output_axis)
        output.to_excel('accmulate_ponit.xlsx', index=False)


field = splitfield(99, 66, 3)
field.draw_graphic()
field.accumulate_point()
